home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Game Programming in C++ - Start to Finish
/
GameProgrammingS.iso
/
Peon
/
PeonSDK-Win32-1.0.0.exe
/
{app}
/
PeonMain
/
source
/
SceneTexture.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
2005-09-26
|
3KB
|
136 lines
#include "SceneTexture.h"
namespace peon
{
SceneTexture::SceneTexture()
{
}
SceneTexture::~SceneTexture()
{
glDeleteTextures(1, &m_tex );
}
bool SceneTexture::loadImage( const String& strFilename, bool bAlpha,
bool bMipMaps, bool bRepeat )
{
//load the image data to an SDL_Surface structure
SDL_Surface* pTexSurface = IMG_Load( strFilename.c_str() );
if( NULL == pTexSurface )
{
//error
return false;
}
//calculate the total size of the image data. If you are needing
//the alpha channel then account for that
int dim = pTexSurface->w * pTexSurface->h * ((bAlpha) ? 4: 3);
GLubyte *pData = new GLubyte[ dim ];
//loop through our SDL_Surface and copy it into the array
//if the image has an extra alpha channel of information then
//be sure to append that
int pos = 0;
for( int y = (pTexSurface->h) - 1; y > -1; y-- )
{
for(int x = 0; x < pTexSurface->w; x++)
{
Uint8 r, g, b, a;
//getPixel is defined in the SDL documentation. It just
//grabs the pixel data from a given SDL_Surface at
//coordinates x,y
Uint32 color = getPixel(pTexSurface, x, y);
if(!bAlpha)
SDL_GetRGB( color, pTexSurface->format, &r, &g, &b);
else
SDL_GetRGBA( color, pTexSurface->format, &r, &g, &b, &a);
pData[pos] = r; pos++;
pData[pos] = g; pos++;
pData[pos] = b; pos++;
if( bAlpha )
pData[pos] = a; pos++;
}
}
int type = (bAlpha) ? GL_RGBA : GL_RGB;
glGenTextures(1, &m_tex); // Generate texture ID
glBindTexture(GL_TEXTURE_2D, m_tex);
int filter_min, filter_mag;
filter_min = (bMipMaps) ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST;
filter_mag = GL_NEAREST;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
filter_min);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
filter_mag);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
(bRepeat) ? GL_REPEAT : GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
(bRepeat) ? GL_REPEAT : GL_CLAMP);
if(bMipMaps)
{
gluBuild2DMipmaps(GL_TEXTURE_2D, type, pTexSurface->w, pTexSurface->h,
type, GL_UNSIGNED_BYTE, pData);
}else
{
glTexImage2D(GL_TEXTURE_2D, 0, type, pTexSurface->w,
pTexSurface->h, 0, type, GL_UNSIGNED_BYTE, pData);
}
//now that we are finished, do some garbage collection
//clean up our array and destroy the surface you loaded
delete [] pData;
SDL_FreeSurface( pTexSurface );
//return the texture handle
return true;
}
/*
* Return the pixel value at (x, y)
* NOTE: The surface must be locked before calling this!
* Taken from SDL documentation.
*/
Uint32 SceneTexture::getPixel(SDL_Surface *surface, int x, int y)
{
int bpp = surface->format->BytesPerPixel;
/* Here p is the address to the pixel we want to retrieve */
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
switch(bpp) {
case 1:
return *p;
case 2:
return *(Uint16 *)p;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
return p[0] << 16 | p[1] << 8 | p[2];
else
return p[0] | p[1] << 8 | p[2] << 16;
case 4:
return *(Uint32 *)p;
default:
return 0; /* shouldn't happen, but avoids warnings */
}
}
}